package edu.ccut.saturn.studio.saturndata.dialog;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

import edu.ccut.saturn.component.IValidateInfo;
import edu.ccut.saturn.component.impl.SaturnValidateUseInfo;
import edu.ccut.saturn.studio.Activator;
import edu.ccut.saturn.studio.Images;
import edu.ccut.saturn.studio.core.saturnproperty.StringUtils;
import edu.ccut.saturn.studio.core.util.eclipse.Messages;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnDialogUtil;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnSWTUtils;
import edu.ccut.saturn.studio.database.model.DBConnection;
import edu.ccut.saturn.studio.database.model.DBConnectionProvider;
import edu.ccut.saturn.studio.database.model.SqlColumn;
import edu.ccut.saturn.studio.database.model.DBConnection.DBConnectionListener;
import edu.ccut.saturn.studio.saturndata.model.DataItem;
import edu.ccut.saturn.studio.saturndata.model.JavaTypeUtils;

/**
 * 添加数据库表对话框
 */

public class DateItemAddByTableDialog extends TitleAreaDialog {

	private static final char START = '*';

	private TableViewer tableView;

	private Text filterTest;

	private String connectname = "";//$NON-NLS-1$

	private DBConnection dbConnection = null;

	private CheckboxTableViewer checkboxTableView;

	private List<DataItem> allDataItems = new ArrayList<DataItem>();
	private List<DataItem> checkedDataItems = new ArrayList<DataItem>();

	private Object[] tableNames = null;
	private Object[] viewNames = null;

	private Text nameText;

	public DateItemAddByTableDialog(Shell parentShell, String connectname) {
		super(parentShell);

		this.dbConnection = DBConnectionProvider.getInstance().getConnection(
				connectname);
		this.connectname = connectname;
	}

	protected Control createContents(Composite parent) {
		Control contents = super.createContents(parent);
		// 设置标题
		setTitle(Messages.getString("DateItemAddByTableDialog.adddata")); //$NON-NLS-1$
		// 设置对话框样式效果
		setMessage(Messages
				.getString("DateItemAddByTableDialog.choosetablefield")); //$NON-NLS-1$
		return contents;
	}

	// 初始化界面大小
	protected Point getInitialSize() {
		return new Point(450, 550);
	}

	protected Control createDialogArea(Composite parent) {
		getShell().setText(
				Messages.getString("DateItemAddByTableDialog.adddatafield")); //$NON-NLS-1$
		Composite composite = new Composite(parent, SWT.NONE);

		final GridData gd_composite = new GridData(SWT.FILL, SWT.FILL, true,
				true);
		gd_composite.heightHint = 331;
		gd_composite.widthHint = 493;
		gd_composite.verticalIndent = 7;
		gd_composite.horizontalIndent = 14;
		composite.setLayoutData(gd_composite);
		final GridLayout gridLayout = new GridLayout(5, false);
		gridLayout.marginRight = 10;
		composite.setLayout(gridLayout);

		final Label TestLabel = new Label(composite, SWT.NONE);
		GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
		labelData.horizontalSpan = 4;
		TestLabel.setLayoutData(labelData);
		TestLabel
				.setText(Messages.getString("DateItemAddByTableDialog.filter") + Messages.getString("DateItemAddByTableDialog.stringlimit")); //$NON-NLS-1$ //$NON-NLS-2$

		final Button button = new Button(composite, SWT.NONE);
		GridData gridData = new GridData(60, 20);
		button.setLayoutData(gridData);
		button.setText(Messages.getString("DateItemAddByTableDialog.confirm")); //$NON-NLS-1$
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				String tableName = nameText.getText().trim();
				String filterStr = filterTest.getText().trim();

				if (StringUtils.isNotEmpty(tableName)
						&& StringUtils.isNotEmpty(filterStr)) {

					String[] filterValues = filterStr.split(","); //$NON-NLS-1$

					Set<DataItem> filterlist = new HashSet<DataItem>();

					for (String filter : filterValues) {
						filter = filter.trim();
						int length = filter.length();
						int startPosition = filter.indexOf(START);
						int endPosition = filter.lastIndexOf(START);

						if (startPosition < 0) {
							for (int j = 0; j < allDataItems.size(); j++) {
								DataItem fieldVo = allDataItems.get(j);

								if (fieldVo.getColumn()
										.equalsIgnoreCase(filter)) {

									filterlist.add(fieldVo);
								}

							}
						}

						if (startPosition == length - 1) {
							String matchStr = filter
									.substring(0, startPosition).toUpperCase();

							for (int j = 0; j < allDataItems.size(); j++) {
								DataItem fieldVo = allDataItems.get(j);

								if (fieldVo.getColumn().startsWith(matchStr)) {
									filterlist.add(fieldVo);
								}

							}
						}

						if (startPosition == 0 && endPosition != length - 1) {
							String matchStr = filter.substring(
									startPosition + 1).toUpperCase();

							for (int j = 0; j < allDataItems.size(); j++) {
								DataItem fieldVo = allDataItems.get(j);

								if (fieldVo.getColumn().endsWith(matchStr)) {
									filterlist.add(fieldVo);
								}

							}
						}

						if (startPosition == 0 && endPosition == length - 1) {
							String Matchingstr = filter.substring(1,
									endPosition).toUpperCase();

							for (int j = 0; j < allDataItems.size(); j++) {
								DataItem fieldVo = allDataItems.get(j);

								if (fieldVo.getColumn().toUpperCase().indexOf(
										Matchingstr) >= 0) {
									filterlist.add(fieldVo);
								}

							}
						}
					}

					tableView.setInput(new ArrayList<DataItem>(filterlist));
				} else {
					tableView.setInput(allDataItems);
				}
			}
		});

		filterTest = new Text(composite, SWT.BORDER | SWT.H_SCROLL
				| SWT.V_SCROLL | SWT.WRAP);
		final GridData gd_sqlTest = new GridData(SWT.FILL, SWT.FILL, true,
				false);
		gd_sqlTest.horizontalSpan = 5;
		gd_sqlTest.heightHint = 76;
		filterTest.setLayoutData(gd_sqlTest);

		nameText = new Text(composite, SWT.BORDER);
		final GridData gd_text = new GridData(SWT.FILL, SWT.CENTER, true, false);
		gd_text.horizontalSpan = 3;
		nameText.setLayoutData(gd_text);
		nameText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String dbname = nameText.getText();

				List<SqlColumn> sqlColumns = new ArrayList<SqlColumn>();
				try {

					String databaseName = dbConnection.getDatabaseName();

					sqlColumns = dbConnection.getTableColumns(databaseName,
							dbname);
				} catch (Exception e1) {
					e1.printStackTrace();
				}

				allDataItems = new ArrayList<DataItem>();
				for (int j = 0; j < sqlColumns.size(); j++) {
					DataItem fieldVo = createDataItme(sqlColumns.get(j));

					allDataItems.add(fieldVo);
				}

				tableView.setInput(allDataItems);
			}
		});
		final Button tableBrowertableButton = new Button(composite, SWT.NONE);
		tableBrowertableButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				dbConnection.getConnectionAsync(new DBConnectionListener() {
					public void onGetConnection(Connection connection) {
						getShell().getDisplay().asyncExec(new Runnable() {
							public void run() {
								ElementListSelectionDialog dialog = SaturnDialogUtil
										.createElementListSelectionDialog(
												getShell(),
												new SaturnSWTUtils.SaturnLabelDefaultProvider() {
													public Image getImage(
															Object element) {
														return Activator
																.getImage(Images.DATABASE_TABLE);
													}

													public String getText(
															Object element) {
														return element
																.toString();
													}
												});

								dialog
										.setTitle(Messages
												.getString("DateItemAddByTableDialog.choosetable")); //$NON-NLS-1$
								dialog
										.setMessage(Messages
												.getString("DateItemAddByTableDialog.pleasechoosetable")); //$NON-NLS-1$
								dialog.setElements(getTableNames());
								if (dialog.open() == Window.OK) {
									nameText.setText((String) dialog
											.getFirstResult());
								}
							}
						});
					}
				});
			}
		});
		final GridData gd_tableBrowertableButton = new GridData(60, 20);
		tableBrowertableButton.setLayoutData(gd_tableBrowertableButton);
		tableBrowertableButton.setText(Messages
				.getString("DateItemAddByTableDialog.browsetable")); //$NON-NLS-1$

		final Button BrowerViewButton = new Button(composite, SWT.NONE);
		BrowerViewButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				dbConnection.getConnectionAsync(new DBConnectionListener() {
					public void onGetConnection(Connection connection) {
						getShell().getDisplay().asyncExec(new Runnable() {
							public void run() {
								ElementListSelectionDialog dialog = SaturnDialogUtil
										.createElementListSelectionDialog(
												getShell(),
												new SaturnSWTUtils.SaturnLabelDefaultProvider() {
													public Image getImage(
															Object element) {
														return Activator
																.getImage(Images.DATABASE_VIEW);
													}

													public String getText(
															Object element) {
														return element
																.toString();
													}
												});
								dialog
										.setTitle(Messages
												.getString("DateItemAddByTableDialog.chooseview")); //$NON-NLS-1$
								dialog
										.setMessage(Messages
												.getString("DateItemAddByTableDialog.pleasechooseview")); //$NON-NLS-1$
								dialog.setElements(getViewNames());
								if (dialog.open() == Window.OK) {
									nameText.setText((String) dialog
											.getFirstResult());
								}
							}
						});
					}
				});
			}
		});

		final GridData gd_viewBrowerButton = new GridData(60, 20);
		BrowerViewButton.setLayoutData(gd_viewBrowerButton);
		BrowerViewButton.setText(Messages
				.getString("DateItemAddByTableDialog.browseview")); //$NON-NLS-1$

		tableView = new TableViewer(composite, SWT.CHECK | SWT.MULTI
				| SWT.BORDER | SWT.FULL_SELECTION);

		Table table = tableView.getTable();

		checkboxTableView = new CheckboxTableViewer(tableView.getTable());
		table.getHorizontalBar().addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
			}
		});
		GridData gridData1 = new GridData(SWT.FILL, SWT.FILL, true, true);
		gridData1.horizontalSpan = 5;
		table.setLayoutData(gridData1);
		table.setHeaderVisible(true); // 显示表头
		table.setLinesVisible(true); // 显示表格线

		tableView
				.setContentProvider(new SaturnSWTUtils.SaturnTableViewerDefaultContentProvider());
		tableView
				.setLabelProvider(new SaturnSWTUtils.SaturnTableViewerDefaultLabelProvider() {
					public String getColumnText(Object element, int columnIndex) {
						DataItem columnVO = (DataItem) element;
						if (columnIndex == 1) {
							return columnVO.getName();
						}
						if (columnIndex == 2) {
							return columnVO.getColumn();
						}
						if (columnIndex == 3) {
							return columnVO.getTableName();
						}

						if (columnIndex == 4) {
							return columnVO.getType();
						}
						if (columnIndex == 5) {
							return columnVO.getJavaType();
						}

						return ""; //$NON-NLS-1$
					}
				});
		/**
		 * 建立TableView的列
		 */

		TableColumn column1 = new TableColumn(table, SWT.NULL);
		column1.setText(Messages
				.getString("DateItemAddByTableDialog.choosefield")); //$NON-NLS-1$
		column1.setWidth(65);

		TableColumn column2 = new TableColumn(table, SWT.NONE);
		column2.setText(Messages
				.getString("DateItemAddByTableDialog.fieldname")); //$NON-NLS-1$
		column2.setWidth(65);

		TableColumn column3 = new TableColumn(table, SWT.NONE);
		column3.setText(Messages
				.getString("DateItemAddByTableDialog.columnname")); //$NON-NLS-1$
		column3.setWidth(60);
		TableColumn column4 = new TableColumn(table, SWT.NONE);
		column4.setText(Messages
				.getString("DateItemAddByTableDialog.tablename")); //$NON-NLS-1$
		column4.setWidth(60);
		TableColumn column5 = new TableColumn(table, SWT.NONE);
		column5.setText(Messages
				.getString("DateItemAddByTableDialog.fieldtype")); //$NON-NLS-1$
		column5.setWidth(69);
		TableColumn column6 = new TableColumn(table, SWT.NONE);
		column6
				.setText(Messages
						.getString("DateItemAddByTableDialog.javatype")); //$NON-NLS-1$
		column6.setWidth(95);

		new Label(composite, SWT.NONE);

		return parent;
	}

	/**
	 * 用 SWT.RESIZE、SWT.MAX、SWT.MIN 分别设置窗口为可变大小、可最大化、可最小化
	 */
	protected int getShellStyle() {
		return super.getShellStyle() | SWT.MIN | SWT.MAX | SWT.RESIZE;
	}

	// 添加完成按钮
	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.SELECT_ALL_ID, Messages
				.getString("DateItemAddByTableDialog.checkall"), true); //$NON-NLS-1$
		createButton(parent, IDialogConstants.CLOSE_ID, Messages
				.getString("DateItemAddByTableDialog.antichoose"), true); //$NON-NLS-1$
		createButton(parent, IDialogConstants.OK_ID, Messages
				.getString("DateItemAddByTableDialog.add"), true); //$NON-NLS-1$
		createButton(parent, IDialogConstants.CANCEL_ID, Messages
				.getString("DateItemAddByTableDialog.cancel"), true); //$NON-NLS-1$
	}

	@Override
	public boolean close() {
		if (this.dbConnection != null) {
			try {
				dbConnection.closeConnection();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return super.close();
	}

	protected void buttonPressed(int buttonId) {
		if (buttonId == IDialogConstants.SELECT_ALL_ID) {
			checkboxTableView.setAllChecked(true);
		}

		if (buttonId == IDialogConstants.CLOSE_ID) {
			TableItem[] checkObj = checkboxTableView.getTable().getItems();
			for (int a = 0; a < checkObj.length; a++) {
				if (checkObj[a].getChecked()) {
					checkObj[a].setChecked(false);
				} else {
					checkObj[a].setChecked(true);
				}
			}
		}

		if (buttonId == IDialogConstants.CANCEL_ID) {
			close();
		}

		if (buttonId == IDialogConstants.OK_ID) {
			if (checkboxTableView != null) {
				Object[] checkedObjects = checkboxTableView
						.getCheckedElements();
				if (checkedObjects.length != 0) {
					for (Object checkedObject : checkedObjects) {
						DataItem dataItem = (DataItem) checkedObject;
						dataItem.setName(dataItem.getName().toLowerCase());
						checkedDataItems.add(dataItem);
					}
					super.buttonPressed(buttonId);
				} else {
					SaturnDialogUtil.openInformation(getShell(), Messages
							.getString("DateItemAddByTableDialog.choosefirst")); //$NON-NLS-1$
				}
			}
		}
	}

	public List<DataItem> getCheckedDataItems() {
		return this.checkedDataItems;
	}

	public String getConnectname() {
		return connectname;
	}

	public void setConnectname(String connectname) {
		this.connectname = connectname;
	}

	private Object[] getTableNames() {
		if (this.tableNames == null || this.viewNames == null) {
			initalTableAndView();
		}

		return tableNames;
	}

	private Object[] getViewNames() {
		if (this.tableNames == null || this.viewNames == null) {
			initalTableAndView();
		}

		return viewNames;
	}

	private void initalTableAndView() {
		try {
			List<String> tableList = dbConnection.getTableNames(dbConnection
					.getDatabaseName()); //$NON-NLS-1$
			List<String> viewList = dbConnection.getViewNames(dbConnection
					.getDatabaseName()); //$NON-NLS-1$

			tableNames = tableList.toArray();
			viewNames = viewList.toArray();
		} catch (Exception e) {
			SaturnDialogUtil
					.openError(
							getShell(),
							Messages
									.getString("DateItemAddByTableDialog.errorlinkfordatabase")); //$NON-NLS-1$
		}
	}

	private DataItem createDataItme(SqlColumn sqlColumn) {
		DataItem item = new DataItem();

		item.setName(sqlColumn.getName().toLowerCase());
		item.setColumn(sqlColumn.getName().toUpperCase());
		item.setColumnAlias(""); //$NON-NLS-1$
		item.setTableName(sqlColumn.getTableName());
		item.setLength(sqlColumn.getColumnLenth() + ""); //$NON-NLS-1$
		item.setJavaType(JavaTypeUtils.getColumnJavaType(
				dbConnection.getType(), sqlColumn.getColumnDataType()));
		item.setType(sqlColumn.getColumnDataType().toUpperCase());
		item.setDefaultValue(""); //$NON-NLS-1$
		item.setDictTypeId(""); //$NON-NLS-1$
		item.setShowName(""); //$NON-NLS-1$
		item.setIsPrimaryKey(""); //$NON-NLS-1$
		item.setSequenceName(""); //$NON-NLS-1$
		item.setValidateUseInfo(new SaturnValidateUseInfo(item.getName()
				.toUpperCase(), item.getJavaType(), false,
				new ArrayList<IValidateInfo>()));

		return item;
	}
}
